package com.gzcstec.ftp;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * FTP自定义工厂类
 */
public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {

    private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class);
    private FTPClientPoolProperties ftpClientPoolProperties;

    public FTPClientFactory(FTPClientPoolProperties ftpClientPoolProperties) {
        this.ftpClientPoolProperties = ftpClientPoolProperties;
    }

    /**
     * 新建对象
     */
    @Override
    public FTPClient create() throws Exception {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setConnectTimeout(ftpClientPoolProperties.getClientTimeout());
        ftpClient.connect(ftpClientPoolProperties.getHost(), ftpClientPoolProperties.getPort());
        int reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            throw new RuntimeException("could not connect to ftp server:" + ftpClientPoolProperties.getHost() + ":" + ftpClientPoolProperties.getPort());
        }
        boolean result = ftpClient.login(ftpClientPoolProperties.getUsername(), ftpClientPoolProperties.getPassword());
        if (!result) {
            throw new RuntimeException("login ftp server failed userName:" + ftpClientPoolProperties.getUsername());
        }
        ftpClient.setFileType(ftpClientPoolProperties.getTransferFileType());
        ftpClient.setBufferSize(ftpClientPoolProperties.getBufferSize());
        ftpClient.setControlEncoding(ftpClientPoolProperties.getEncoding());
        if (ftpClientPoolProperties.isPassiveMode()) {
            ftpClient.enterLocalPassiveMode();
        }
        return ftpClient;
    }

    @Override
    public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
        return new DefaultPooledObject(ftpClient);
    }

    /**
     * 销毁对象
     */
    @Override
    public void destroyObject(PooledObject<FTPClient> p) throws Exception {
        FTPClient ftpClient = p.getObject();
        ftpClient.noop();
        ftpClient.logout();
        if (ftpClient.isConnected()) {
            try {
                ftpClient.disconnect();
            } catch (IOException f) {
            }
        }
        super.destroyObject(p);
    }

    /**
     * 验证对象
     */
    @Override
    public boolean validateObject(PooledObject<FTPClient> p) {
        FTPClient ftpClient = p.getObject();
        boolean connect = false;
        try {
            connect = ftpClient.sendNoOp();
//            if (connect) {
//                ftpClient.changeWorkingDirectory(this.ftpClientPoolProperties.getFileSeparator());
//            }
        } catch (IOException e) {
            logger.error("validate FTPClient exception ", e);
        }
        return connect;
    }
}
